#include "grid.h"


/*****************************************
/*          Statics
/*****************************************/

    /*****************************************/
    /*          Proprties
    /*****************************************/

        Grid::s_DefaultWidth    =1;
        Grid::s_DefaultHeight   =1;
        Grid::s_DefaultDepth    =1;

/*****************************************
/*          Constructors
/*****************************************/

    Grid::Grid()
    {
        Initialize(m_DefaultWidth, m_DefaultHeight, m_DefaultDepth);
    }

    Grid::Grid(int width)
    {
        Initialize(width, s_De)
    }
    Grid::Grid(int width, int height)
    {
        Initialize(width, height, m_DefaultDepth);
    }

    Grid::Grid(int width, int height, int depth)
    {
        Initialize(width, height, depth);
    }

    void Grid::Initialize(int width, int height, int depth)
    {
        m_Width     = width;
        m_Height    = height;
        m_Depth     = depth;

        m_SupCells = new List<SupCell<T>>();

        InitializeCells();
    }

/*****************************************
/*          Methods
/*****************************************/

    /*****************************************
    /*          Members
    /*****************************************/

        void Grid::InitializeCells()
        {
            m_Cells = new Cell<T>[Depth(), Height(), Width()];

            for (int i = 0; i < Depth(); i++)
            {
                for (int j = 0; j < Height(); j++)
                {
                    for (int k = 0; k < Width(); k++)
                    {
                        m_Cells[i, j, k] = new Cell<T>(k, j, i);
                    }
                }
            }
        }

        bool Grid::IsThereEnoughSpace(int x, int y, SupCell<T> cell)
        {
            return IsThereEnoughSpace( x,  y,  0, cell);
        }

        bool Grid::IsThereEnoughSpace(int x, int y, int z, SupCell<T> cell)
        {
            bool enoughSpace = true;

            // First, I must check if the Cell fit inside the grid


            if (
                    (Common.IsBetween(x, 0, Width()))   &&  (Common.IsBetween(x + cell.Width(), 0, Width())) &&

                    (Common.IsBetween(y, 0, Height()))  &&  (Common.IsBetween(y + cell.Height(), 0, Height())) &&

                    (Common.IsBetween(z, 0, Depth()))   &&  (Common.IsBetween(z + cell.Depth(), 0, Depth()))
                )

            {
                for (int i = 0; i < cell.Depth(); i++)
                {
                    for (int j = 0; j < cell.Height(); j++)
                    {
                        for(int k=0; k< cell.Width(); k++)
                        {
                            if (cell.m_Mask[i, j, k] == 1 && m_Cells[z + i, y + j, x+k].m_Reference != null)
                            {
                                enoughSpace = false;
                            }
                        }
                    }
                }
            }
            else
            {
                return false;
            }
            return enoughSpace;
        }


        bool Grid::Insert(SupCell<T> cell, int x, int y, int z)
        {
            //  First, I check if the cell isn't already inside the grid

            if(m_SupCells.Contains(cell))
            {
                return false;
            }

            if (IsThereEnoughSpace(x, y, z, cell))
            {
                cell.X = x;
                cell.Y = y;
                cell.Z = z;

                m_SupCells.Add(cell);
                FillSpace(cell);
                return true;
            }

            return false;
        }


        void Grid::FillSpace(SupCell<T> cell)
        {
            for (int i = 0; i < cell.Depth(); i++)
            {
                for (int j = 0; j < cell.Height(); j++)
                {
                    for (int k = 0; k < cell.Width(); k++)
                    {
                        Debug.Log(cell.m_Mask[i,j,k]);

                        if (cell.m_Mask[i, j, k] == 1)
                        {
                            m_Cells[cell.Z + i, cell.Y + j, cell.X + k].m_Reference = cell;
                        }
                    }
                }
            }
        }


        void Grid::Remove(SupCell<T> cell)
        {
            for (int i = 0; i < cell.Depth(); i++)
            {
                for (int j = 0; j < cell.Height(); j++)
                {
                    for (int k = 0; k < cell.Width(); k++)
                    {
                        if (cell.m_Mask[i, j, k] == 1)
                        {
                            m_Cells[cell.Z + i, cell.Y + j, cell.X + k].m_Reference = null;
                        }
                    }
                }
            }
            m_SupCells.Remove(cell);
        }
}
